<?php
// +----------------------------------------------------------------------
// | RXThinkCMF敏捷开发框架 [ 赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | 版权所有 2018~2023 南京RXThinkCMF研发中心
// +----------------------------------------------------------------------
// | Licensed LGPL-3.0 RXThinkCMF并不是自由软件，未经许可禁止去掉相关版权
// +----------------------------------------------------------------------
// | 官方网站: https://www.rxthink.cn
// +----------------------------------------------------------------------
// | Author: @牧羊人 团队荣誉出品
// +----------------------------------------------------------------------
// | 版权和免责声明:
// | 本团队对该软件框架产品拥有知识产权（包括但不限于商标权、专利权、著作权、商业秘密等）
// | 均受到相关法律法规的保护，任何个人、组织和单位不得在未经本团队书面授权的情况下对所授权
// | 软件框架产品本身申请相关的知识产权，禁止用于任何违法、侵害他人合法权益等恶意的行为，禁
// | 止用于任何违反我国法律法规的一切项目研发，任何个人、组织和单位用于项目研发而产生的任何
// | 意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、
// | 附带或衍生的损失等)，本团队不承担任何法律责任，本软件框架禁止任何单位和个人、组织用于
// | 任何违法、侵害他人合法利益等恶意的行为，如有发现违规、违法的犯罪行为，本团队将无条件配
// | 合公安机关调查取证同时保留一切以法律手段起诉的权利，本软件框架只能用于公司和个人内部的
// | 法律所允许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

namespace app\admin\model;


use think\Db;

/**
 * 行为日志-模型
 * @author 牧羊人
 * @since 2020/11/19
 * Class ActionLog
 * @package app\admin\model
 */
class ActionLog extends BaseModel
{
    // 设置数据表
    protected $table = null;
    // 自定义日志标题
    protected static $title = '';
    // 自定义日志内容
    protected static $content = '';

    /**
     * 构造函数
     * @param array $data
     * @since 2020/11/14
     * ActionLog constructor.
     * @author 牧羊人
     */
    public function __construct(array $data = [])
    {
        parent::__construct($data);
        // 设置表名
        $this->table = DB_PREFIX . 'action_log_' . date('Y') . '_' . date('m');
        // 初始化行为日志表
        $this->initTable();

    }


    /**
     * 初始化日志表
     * @return string|null
     * @throws \think\db\exception\BindParamException
     * @author 牧羊人
     * @since 2020/11/14
     */
    private function initTable()
    {
        $tbl = $this->table;
        if (!$this->tableExists($tbl)) {
            $sql = "CREATE TABLE `{$tbl}` (
                  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '唯一性标识',
                  `log_sn` varchar(60) CHARACTER SET utf8mb4 NOT NULL COMMENT '日志编号',
                  `username` varchar(60) CHARACTER SET utf8mb4 NOT NULL COMMENT '操作人用户名',
                  `method` varchar(20) CHARACTER SET utf8mb4 NOT NULL COMMENT '请求类型',
                  `module` varchar(30) NOT NULL COMMENT '模型',
                  `action` varchar(255) NOT NULL COMMENT '操作方法',
                  `url` varchar(200) CHARACTER SET utf8mb4 NOT NULL COMMENT '操作页面',
                  `param` text CHARACTER SET utf8mb4 NOT NULL COMMENT '请求参数(JSON格式)',
                  `title` varchar(100) NOT NULL COMMENT '日志标题',
                  `type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '操作类型：1登录系统 2注销系统 3操作日志',
                  `node` varchar(100) NOT NULL COMMENT '日志节点',
                  `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容',
                  `ip` varchar(18) CHARACTER SET utf8mb4 NOT NULL COMMENT 'IP地址',
                  `user_agent` varchar(360) CHARACTER SET utf8mb4 NOT NULL COMMENT 'User-Agent',
                  `create_user` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '添加人',
                  `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '添加时间',
                  `mark` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '有效标识：1正常 0删除',
                  PRIMARY KEY (`id`) USING BTREE
                ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='系统行为日志表';";
            Db::query($sql);

        }
        return $tbl;
    }

    /**
     * 设置标题
     * @param $title 标题
     * @since 2020/11/14
     * @author 牧羊人
     */
    public static function setTitle($title)
    {
        self::$title = $title;
    }

    /**
     * 设置内容
     * @param $content 内容
     * @since 2020/11/14
     * @author 牧羊人
     */
    public static function setContent($content)
    {
        self::$content = $content;
    }

    /**
     * 创建日志
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @since 2020/11/20
     * @author 牧羊人
     */
    public static function record()
    {
        if (!self::$title) {
            // 操作控制器名
            $menuModel = new Menu();
            $info = $menuModel->getOne([
                ['path', '=', request()->url()],
            ]);
            if ($info) {
                if ($info['type'] == 1) {
                    $menuInfo = $menuModel->getInfo($info['pid']);
                    self::$title = $menuInfo['title'];
                } else {
                    self::$title = $info['title'];
                }
            }
        }

        $action = request()->url();

        // 日志数据
        $data = [
            'username' => '管理员',
            'log_sn' => '',
            'module' => request()->module(),
            'action' => request()->url(),
            'method' => request()->method(),
            'url' => request()->url(true), // 获取完成URL
            'param' => request()->param() ? json_encode(request()->param()) : '',
            'title' => self::$title ? self::$title : '操作日志',
            'type' => self::$title == '登录系统' ? 1 : (self::$title == '注销系统' ? 2 : 3),
            'node' => '',
            'content' => self::$content,
            'ip' => request()->ip(),
            'user_agent' => request()->server('HTTP_USER_AGENT'),
            'create_user' => get_uid(),
            'create_time' => time(),
        ];
        // 日志入库
        self::insert($data);

        // 业务管理、监控设备管理操作日志
        // device:add edit :delete
        // devideo:add edit delete
        if(in_array($action,['/device/add','/device/edit','/device/delete','/devideo/add','/devideo/edit','/devideo/delete', '/devideo/status'])){
            $logcode = '';
            $logtype = '';
            $name = '';
            $mark = '';

            if(strpos($action,'device')){
                $logcode = 'device';
            }elseif (strpos($action,'devideo')){
                $logcode = 'devideo';
            }

            if(strpos($action,'/add')){

                $logtype = 'add';

                if ($logcode == 'device'){
                    $mark = "添加设备";
                    $name = request()->param('name');

                }elseif ($logcode == 'devideo'){
                    $mark = "添加监控设备";
                    $name = request()->param('video_no');
                }

            }elseif (strpos($action,'/edit')){

                if(request()->param('id') !== null){
                    $logtype = 'edit';

                    if ($logcode == 'device'){
                        $old_info = Device::find(request()->param('id'));
                        $name = $old_info['name'];
                        // 频率
                        if($old_info['run_pinlv'] != request()->param('run_pinlv')){
                            $mark = "设置频率,原频率" . $old_info['run_pinlv'] ."，改为" . request()->param('run_pinlv');
                        }

                        // 产水
                        if($old_info['chanshui'] != request()->param('chanshui')){
                            $mark = "设置产水,原产水" . $old_info['chanshui'] ."，改为" . request()->param('chanshui');
                        }

                        // 传动比
                        if($old_info['chuandongbi'] != request()->param('chuandongbi')){
                            $mark = "设置传动比,原传动比" . $old_info['chuandongbi'] ."，改为" . request()->param('chuandongbi');
                        }

                        // 相对高差
                        if($old_info['xiangdui_high'] != request()->param('xiangdui_high')){
                            $mark = "设置相对高差,原相对高差" . $old_info['xiangdui_high'] ."，改为" . request()->param('xiangdui_high');
                        }

                        // 设备编号
                        if($old_info['device_no'] != request()->param('device_no')){
                            $mark = "修改设备编号,原设备编号" . $old_info['device_no'] ."，改为" . request()->param('device_no');
                        }

                        // 井号
                        if($old_info['name'] != request()->param('name')){
                            $mark = "修改井号,原井号" . $old_info['name'] ."，改为" . request()->param('name');
                        }

                        // 设备类型
                        if($old_info['device_type'] != request()->param('device_type')){
                            $mark = "修改设备类型,原设备类型" . $old_info['device_type'] ."，改为" . request()->param('device_type');
                        }

                        // 位置
                        if($old_info['address'] != request()->param('address')){
                            $mark = "修改位置,原位置" . $old_info['address'] ."，改为" . request()->param('address');
                        }

                        // 备注
                        if($old_info['note'] != request()->param('note')){
                            $mark = "修改备注信息,原备注" . $old_info['note'] ."，改为" . request()->param('note');
                        }

                        // 状态
                        if($old_info['status'] != request()->param('status')){
                            $mark = "修改状态,原状态" . $old_info['status'] ."，改为" . request()->param('status');
                        }

                    }elseif ($logcode == 'devideo'){
                        $old_info = Devideo::find(request()->param('id'));
                        $name = $old_info['video_no'];

                        // 设备编号
                        if($old_info['video_no'] != request()->param('video_no')){
                            $mark = "修改设备编号,原设备编号" . $old_info['video_no'] ."，改为" . request()->param('video_no');
                        }

                        // 设备名称
                        if($old_info['video_name'] != request()->param('video_name')){
                            $mark = "修改设备名称,原设设备名称" . $old_info['video_name'] ."，改为" . request()->param('video_name');
                        }

                        // 安装位置
                        if($old_info['address'] != request()->param('address')){
                            $mark = "修改安装位置,原安装位置" . $old_info['address'] ."，改为" . request()->param('address');
                        }

                        // 监控地址
                        if($old_info['monitor_url'] != request()->param('monitor_url')){
                            $mark = "修改监控地址,原监控地址" . $old_info['monitor_url'] ."，改为" . request()->param('monitor_url');
                        }

                        // 状态
                        if($old_info['status'] != request()->param('status')){
                            $mark = "修改状态,原状态" . $old_info['status'] ."，改为" . request()->param('status');
                        }

                        // 备注
                        if($old_info['note'] != request()->param('note')){
                            $mark = "修改备注信息,原备注" . $old_info['note'] ."，改为" . request()->param('note');
                        }

                        $device_ids = request()->param('device_ids');
                        // 关联设备
                        if($old_info['device_ids'] != implode(',',$device_ids)){
                            $mark = "修改关联设备,原关联设备" . $old_info['device_ids'] ."，改为" . implode(',',$device_ids);
                        }
                    }
                }else{
                    $logtype = 'add';

                    if ($logcode == 'device'){
                        $mark = "添加设备";
                        $name = request()->param('name');

                    }elseif ($logcode == 'devideo'){
                        $mark = "添加监控设备";
                        $name = request()->param('video_no');
                    }
                }

            }elseif (strpos($action,'/delete')){
                $logtype = 'delete';

                if ($logcode == 'device'){
                    $mark = "删除设备";

                }elseif ($logcode == 'devideo'){
                    $mark = "删除监控设备";
                }
            }elseif (strpos($action,'/status')){
                $logtype = 'edit';

                $status = request()->param('status');

                if($status == 1){
                    $mark = '启用监控设备';
                }elseif($status == 2){
                    $mark = '停用监控设备';
                }

            }

            // 解析Token获取用户ID
            $token = request()->header("Authorization");
            $token = str_replace("Bearer ", null, $token);
            $jwt = new \Jwt();
            $userId = $jwt->verifyToken($token);

            $datas = [
                'param' => request()->param() ? json_encode(request()->param()) : '',
                'name' => $name,
                'note' => $mark,
                'logcode' => $logcode,
                'logtype' => $logtype,
                'logpoint' => '',
                'user_id' => $userId,
                'create_time' => time(),
            ];

            Optlog::insert($datas);
        }
    }
}